/**********************************************************************
*   Copyright: (C)2023 LingYun IoT System Studio
*      Author: GuoWenxue<guowenxue@gmail.com> QQ: 281143292
* Description: ISKBoard GPIO simulate I2C Bus Hardware Abstract Layer driver
*
*   ChangeLog:
*        Version    Date       Author            Description
*        V1.0.0  2023.04.3    GuoWenxue      Release initial version
***********************************************************************/

#ifndef INC_I2C_BITBANG_H_
#define INC_I2C_BITBANG_H_

#include "stm32l4xx_hal.h"

#define I2C_CLK_STRETCH_TIMEOUT	  6000

typedef enum i2c_num_e
{
	I2CBUS0,
	I2CBUS1,
	I2CBUSMAX,
} i2c_num_t;

typedef struct i2c_gpio_s
{
	GPIO_TypeDef        *group; /* GPIO group */
	uint16_t             pin;   /* GPIO pin   */
} i2c_gpio_t;

typedef struct i2c_bus_s
{
	uint8_t             bus;  /* Bus number   */
	uint8_t             addr; /* Chip 7bits address */
	i2c_gpio_t          scl;  /* SCL GPIO pin */
	i2c_gpio_t          sda;  /* SDA GPIO pin */
} i2c_bus_t;


/*
 *+---------------------+
 *|  I2C API functions  |
 *+---------------------+
 */

/* I2C bus error number */
enum{
  NO_ERROR       = 0x00, // no error
  ACK_ERROR      = 0x01, // no acknowledgment error
  CHECKSUM_ERROR = 0x02, // checksum mismatch error
  TIMEOUT_ERROR  = 0x04, // timeout error
  PARM_ERROR     = 0x80, // parameter out of range error
};

extern int i2c_init(uint8_t bus, uint8_t addr);

extern int i2c_term(uint8_t bus);

extern int i2c_read(uint8_t bus, uint8_t *buf, int size);

extern int i2c_write(uint8_t bus, uint8_t *data, int bytes);

extern void I2C_StartCondition(uint8_t bus);

extern void I2C_StopCondition(uint8_t bus);

/* I2C从设备芯片器件读写方向位器件地址 */
#define R_ADDR(x)     ((x)<<1 | 1) /* I2C地址最低位为1表示读 */
#define W_ADDR(x)     ((x)<<1 )    /* I2C地址最低位为0表示写 */
enum
{
	I2C_WR,	 /* 写方向 */
	I2C_RD,  /* 读方向 */
};
extern uint8_t I2C_SendAddress(uint8_t bus, uint8_t dir);

extern uint8_t I2C_WriteByte(uint8_t bus, uint8_t txByte);

enum
{
	ACK_NONE, /* 不回ACK */
	ACK,      /* 回ACK */
	NAK,      /* 回NAK */
};
extern uint8_t I2C_ReadByte(uint8_t bus, uint8_t *rxByte, uint8_t ack, uint32_t timeout);

#endif /* INC_I2C_BITBANG_H_ */
